/*24009180008王文皓*/

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#include "iot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "iot_gpio.h"
#include "iot_errno.h"
#include "iot_pwm.h"
#include "iot_i2c.h"
#include "iot_adc.h"

#include "hi_time.h"
#include "hi_io.h"
#include "hi_errno.h"
#include "hi_adc.h"

#include "pca9555.h"
#include "ssd1306_fonts.h"
#include "oled_ssd1306.h"
#include "iot_watchdog.h"

// 蜂鸣器参数配置
#define IOT_PWM_PORT_PWM0 0
#define IOT_PWM_PORT_PWM1 1
#define IOT_PWM_PORT_PWM2 2
#define IOT_PWM_PORT_PWM3 3
#define IOT_FREQ 65535
#define IOT_DUTY 20
// i2c参数配置
#define IOT_I2C_IDX_BAUDRATE (400 * 1000)
#define INS5902_I2C_IDX 0
#define DECIMA 10
#define HEX 16
// 线程创建参数
#define NUM 1
#define STACK_SIZE 1024
// MQ-7参数配置
#define MQ7_ADC_CHANNEL IOT_ADC_CHANNEL_5  // 使用ADC通道5
#define MQ7_AO_PIN IOT_IO_NAME_GPIO_11     // AO引脚连接GPIO11(ADC输入)
#define MQ7_DO_PIN IOT_IO_NAME_GPIO_10    // DO引脚连接GPIO10(数字输入)
#define DANGER_THRESHOLD 1100              // 危险阈值
static uint32_t gas_value = 0;            // 全局变量，存储气体浓度值
// 光敏传感器参数配置
#define LIGHT_ADC_CHANNEL IOT_ADC_CHANNEL_4  // 使用ADC通道4
#define LIGHT_AO_PIN IOT_IO_NAME_GPIO_9     // AO引脚连接GPIO9
#define LIGHT_DO_PIN IOT_IO_NAME_GPIO_8    // DO引脚连接GPIO8 
#define LIGHT_THRESHOLD 600                // 光线阈值
static uint32_t light_value = 0;           // 全局变量，存储光线强度值
// 交通灯参数配置
#define DWHITE_LED 0x38+0x07

// MQ-7初始化函数
void MQ7_Init(void)
{
    // 初始化AO引脚(ADC通道)
    IoTGpioInit(MQ7_AO_PIN);
    IoSetFunc(MQ7_AO_PIN, IOT_IO_FUNC_GPIO_11_GPIO);
    IoTGpioSetDir(MQ7_AO_PIN, IOT_GPIO_DIR_IN);
    
    // 初始化DO引脚(数字输入)
    IoTGpioInit(MQ7_DO_PIN);
    IoSetFunc(MQ7_DO_PIN, IOT_IO_FUNC_GPIO_10_GPIO);
    IoTGpioSetDir(MQ7_DO_PIN, IOT_GPIO_DIR_IN);
    
    printf("MQ-7 sensor initialized\r\n");
}
// 获取MQ-7传感器值
void GetMQ7Data(void)
{
    unsigned short data = 0;
    IotGpioValue do_value;
    
    // 读取AO模拟值
    int ret = AdcRead(MQ7_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_4, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS) {
        printf("MQ-7 AO read failed\n");
        return;
    }
    
    // 读取DO数字值
    IoTGpioGetInputVal(MQ7_DO_PIN, &do_value);
    
    gas_value = data; // 更新全局变量
    printf("MQ-7 AO: %d, DO: %d\r\n", data, do_value);
    
    // 报警逻辑
    if (data > DANGER_THRESHOLD || do_value == IOT_GPIO_VALUE1) {
        printf("Danger! Gas concentration too high!\r\n");
        IoTPwmStart(IOT_PWM_PORT_PWM3, 10, 3000); // 触发蜂鸣器
    } else {
        IoTPwmStop(IOT_PWM_PORT_PWM3);
    } 
}
// MQ-7检测线程
void MQ7DetectionTask(void)
{
    printf("MQ7DetectionTask init\r\n");
    MQ7_Init();  // 初始化MQ-7传感器
    
    while (1) {
        GetMQ7Data();  // 获取MQ-7数据
        osDelay(500); // 3秒采样间隔
    }
}

// 光敏传感器初始化
void LightSensor_Init(void)
{
    // 初始化AO引脚(ADC通道)
    IoTGpioInit(LIGHT_AO_PIN);
    IoSetFunc(LIGHT_AO_PIN, IOT_IO_FUNC_GPIO_9_GPIO);
    IoTGpioSetDir(LIGHT_AO_PIN, IOT_GPIO_DIR_IN);
    
    // 初始化DO引脚(数字输入)
    IoTGpioInit(LIGHT_DO_PIN);
    IoSetFunc(LIGHT_DO_PIN, IOT_IO_FUNC_GPIO_8_GPIO);
    IoTGpioSetDir(LIGHT_DO_PIN, IOT_GPIO_DIR_IN);
    
    printf("Light sensor initialized\r\n");
}
// 获取光敏传感器值
void GetLightData(void)
{
    unsigned short data = 0;
    IotGpioValue do_value;
    
    // 读取AO模拟值
    int ret = AdcRead(LIGHT_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_4, 
                     IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    if (ret != IOT_SUCCESS) {
        printf("Light sensor AO read failed\n");
        return;
    }
    
    // 读取DO数字值
    IoTGpioGetInputVal(LIGHT_DO_PIN, &do_value);
    
    light_value = data; // 更新全局变量
    printf("Light AO: %d, DO: %d\r\n", data, do_value);
}
// 光敏检测线程
void LightDetectionTask(void)
{
    printf("LightDetectionTask init\r\n");
    
    while (1) {
        GetLightData();
        osDelay(500); // 3秒采样间隔
    }
}

// 蜂鸣器初始化
void GA12N20Init(void)
{
    // GPIO12初始化
    IoTGpioInit(IOT_IO_NAME_GPIO_12);
    // 设置GPIO12的管脚复用关系为PWM3输出
    IoSetFunc(IOT_IO_NAME_GPIO_12, IOT_IO_FUNC_GPIO_12_PWM3_OUT);
    // GPIO12方向设置为输出
    IoTGpioSetDir(IOT_IO_NAME_GPIO_12, IOT_GPIO_DIR_OUT);
    // 初始化PWM3
    IoTPwmInit(IOT_PWM_PORT_PWM3);
}

// i2c初始化
void I2c_init(void)
{
    // I2C初始化
    IoTI2cInit(INS5902_I2C_IDX, IOT_I2C_IDX_BAUDRATE);
    IoTI2cSetBaudrate(INS5902_I2C_IDX, IOT_I2C_IDX_BAUDRATE);
    // 设置GPIO13的管脚复用关系为I2C0_SDA
    IoSetFunc(IOT_IO_NAME_GPIO_13, IOT_IO_FUNC_GPIO_13_I2C0_SDA);
    // 设置GPIO14的管脚复用关系为I2C0_SCL
    IoSetFunc(IOT_IO_NAME_GPIO_14, IOT_IO_FUNC_GPIO_14_I2C0_SCL);
}
// Oled线程
void OledControl1(void)
{
    //OledFillScreen(0);   
    char line1[32] = {0};
    while (1) {
    char gas_status[16] = "SAFE  ";
        if (gas_value > DANGER_THRESHOLD) {
            strcpy(gas_status, "DANGER");
        }
        snprintf(line1, sizeof(line1), "Gas:%d %s", gas_value, gas_status);
 
        OledShowString(0, 1, line1, 2);  // 第一行显示气体数据
        osDelay(500); 
    }
}
void OledControl2(void)
{
    //OledFillScreen(0);   
    char line2[32] = {0};
    while (1) {
        char light_status[16] = "DARK  ";  // 反转状态描述
        if (light_value < LIGHT_THRESHOLD) {  // 保持原判断条件
            strcpy(light_status, "BRIGHT");  // 反转显示文本
            SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, LED_OFF);
        }
        else{
            SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, DWHITE_LED);
        }  
 
        int display_value = 1000 - light_value;
        snprintf(line2, sizeof(line2), "Light:%d %s", display_value, light_status);
        
        OledShowString(0, 5, line2, 2);
        osDelay(500); 
    }
}


static void WorkEntry(void)
{
    GA12N20Init();
    I2c_init();
    MQ7_Init();
    LightSensor_Init();
    // IO扩展芯片初始化
    PCA9555Init();
    // 配置IO扩展芯片的part1的所有管脚为输出
    SetPCA9555GpioValue(PCA9555_PART1_IODIR, PCA9555_OUTPUT);
    // 配置左右三色车灯全灭
    SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, LED_OFF);
    // OLED初始化
    OledInit();
    OledFillScreen(0); 

    osThreadAttr_t attr;

    attr.name = "Thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    // 创建OLED显示线程
    osThreadNew((osThreadFunc_t)OledControl1, NULL, &attr); 
    osThreadNew((osThreadFunc_t)OledControl2, NULL, &attr); 

    // 创建MQ-7检测线程
    osThreadNew((osThreadFunc_t)MQ7DetectionTask, NULL, &attr); 

    // 创建光敏检测线程
    osThreadNew((osThreadFunc_t)LightDetectionTask, NULL, &attr);
}

APP_FEATURE_INIT(WorkEntry);
